package com.bvgol.examples.my.thread.completableFutureTest;/**
 * @Classname Test1
 * @Description TODO
 * @Date 2020/12/28 11:15
 * @Created by GUOCHEN
 */

import lombok.SneakyThrows;

import java.util.concurrent.CompletableFuture;
import java.util.concurrent.ExecutionException;
import java.util.concurrent.TimeUnit;

/**
 * @program: my-spring-completely
 * @description: 模拟low 写法
 * @author: GUOCHEN
 * @create: 2020/12/28 11:15
 */
public class CompletableFutureSimpleDemo {
    //IntStream.range(1,9).boxed().findFirst().toString();

    /**
     * 功能描述:模拟业务代码
     *
     * @param
     * @return: java.lang.String
     * @author: 郭辰
     * @date: 2020/12/28 13:45
     */
    public static String step1() throws Exception {
        TimeUnit.SECONDS.sleep(1);
        System.out.println("step1");
        return "step1";
    }

    /**
     * 功能描述:模拟业务代码
     *
     * @param
     * @return: java.lang.String
     * @author: 郭辰
     * @date: 2020/12/28 13:45
     */
    public static String step2() throws Exception {
        TimeUnit.SECONDS.sleep(1);
        System.out.println("step2");
        return "step2";
    }

    /**
     * 功能描述:模拟业务代码
     *
     * @param
     * @return: java.lang.String
     * @author: 郭辰
     * @date: 2020/12/28 13:45
     */
    public static String step3() throws Exception {
        TimeUnit.SECONDS.sleep(1);
        System.out.println("step3");
        return "step3";
    }

    /**
     * 功能描述:模拟业务代码
     *
     * @param
     * @return: java.lang.String
     * @author: 郭辰
     * @date: 2020/12/28 13:45
     */
    public static String step4() throws Exception {
        TimeUnit.SECONDS.sleep(1);
        System.out.println("step4");
        return "step4";
    }

    /**
     * 功能描述: 模拟业务代码
     *
     * @param
     * @return: java.lang.String
     * @author: 郭辰
     * @date: 2020/12/28 13:46
     */
    public static String step5() throws Exception {
        TimeUnit.SECONDS.sleep(1);
        System.out.println("step5");
        return "step5";
    }

    /**
     * 功能描述: 模拟串行
     *
     * @param
     * @return: void
     * @author: 郭辰
     * @date: 2020/12/28 13:32
     */
    public static void line() throws Exception {
        CompletableFutureSimpleDemo.step1();
        CompletableFutureSimpleDemo.step2();
        CompletableFutureSimpleDemo.step3();
        CompletableFutureSimpleDemo.step4();
        CompletableFutureSimpleDemo.step5();
    }

    /**
     * 功能描述: 全部都异步,保证不了调用顺序
     *
     * @param
     * @return: void
     * @author: 郭辰
     * @date: 2020/12/28 13:32
     */
    public static void completable_supplyAsync() throws Exception {
        CompletableFuture step1 = CompletableFuture.supplyAsync(() -> {
            try {
                return CompletableFutureSimpleDemo.step1();
            } catch (Exception e) {
                e.printStackTrace();
                return null;
            }
        });
        CompletableFuture step2 = CompletableFuture.supplyAsync(() -> {
            try {
                return CompletableFutureSimpleDemo.step2();
            } catch (Exception e) {
                e.printStackTrace();
                return null;
            }
        });
        CompletableFuture step3 = CompletableFuture.supplyAsync(() -> {
            try {
                return CompletableFutureSimpleDemo.step3();
            } catch (Exception e) {
                e.printStackTrace();
                return null;
            }
        });
        CompletableFuture step4 = CompletableFuture.supplyAsync(() -> {
            try {
                return CompletableFutureSimpleDemo.step4();
            } catch (Exception e) {
                e.printStackTrace();
                return null;
            }
        });
        CompletableFuture step5 = CompletableFuture.supplyAsync(() -> {
            try {
                return CompletableFutureSimpleDemo.step5();
            } catch (Exception e) {
                e.printStackTrace();
                return null;
            }
        });
        CompletableFuture.allOf(step1, step2, step3, step4, step5).join();

    }

    /**
     * 功能描述: 实际用法 先串行 并行需要串行结果
     *
     * @param
     * @return: void
     * @author: 郭辰
     * @date: 2020/12/28 13:41
     */
    public static void actual() throws Exception {
        String step1 = CompletableFutureSimpleDemo.step1();
        if (step1 == null || step1.equals("") || step1.equals(" ")) {
            return;
        }
        CompletableFuture step2 = CompletableFuture.supplyAsync(() -> {
            try {
                step1.length();
                return CompletableFutureSimpleDemo.step2();
            } catch (Exception e) {
                e.printStackTrace();
                return null;
            }
        });
        CompletableFuture step3 = CompletableFuture.supplyAsync(() -> {
            try {
                step1.length();
//                int i =1/0;
                return CompletableFutureSimpleDemo.step3();
            } catch (Exception e) {
                e.printStackTrace();
                return null;
            }
        });
        CompletableFuture step4 = CompletableFuture.supplyAsync(() -> {
            try {
                step1.length();
                return CompletableFutureSimpleDemo.step4();
            } catch (Exception e) {
                e.printStackTrace();
                return null;
            }
        });
        CompletableFuture step5 = CompletableFuture.supplyAsync(() -> {
            try {
                step1.length();
                return CompletableFutureSimpleDemo.step5();
            } catch (Exception e) {
                e.printStackTrace();
                return null;
            }
        });
        CompletableFuture.allOf(step2, step3, step4, step5).join();
    }

    /**
     * 功能描述: 测试顺序执行
     * 业务先后问题解决
     *
     * @param agrs
     * @return: java.lang.String
     * @author: 郭辰
     * @date: 2021/3/3 9:35
     */
    public static String testSequence(String agrs) throws ExecutionException, InterruptedException {
        CompletableFuture future = CompletableFuture.supplyAsync(() -> {
            String result = "根据传参去查询" + agrs;
            return result;
        });
        CompletableFuture future2 = future.thenAcceptAsync(o -> {

            try {
                String s = o.toString();
                System.out.println("s = " + s);
                step2();
            } catch (Exception e) {
                e.printStackTrace();
            }
        });

        CompletableFuture.allOf(future2).get();
        return null;
    }

    /**
     * 功能描述:测试顺序+异常
     *
     * @param agrs
     * @return: java.lang.String
     * @author: 郭辰
     * @date: 2021/3/3 9:48
     */
    @SneakyThrows
    public static String testSequenceAndException(String agrs) {
        CompletableFuture first = CompletableFuture.supplyAsync(() -> {
            String result = "根据传参去查询" + agrs;
            return result;
        });
        CompletableFuture future2 = first.thenAcceptAsync(o -> {

            try {
                String s = o.toString();
                System.out.println("s = " + s);
                step2();
            } catch (Exception e) {
                e.printStackTrace();
            }
        });

        CompletableFuture future3 = first.thenApplyAsync(o -> {
            try {
                int a = 10 / 0;
            } catch (Exception e) {
                e.printStackTrace();
            }

            return ""; //return object
        }).exceptionally(o -> {
            System.out.println("异常之后");
            return o;
        });

        CompletableFuture.allOf(future2, future3).get();
        return null;
    }

    public static void main(String[] args) throws Exception {
        long begin = System.currentTimeMillis();
//        Test1.line();//5003 搜有代码块时间合计
//        CompletableFutureSimpleDemo.completable_supplyAsync();//1074 全部并行
//        CompletableFutureSimpleDemo.actual();//2055
        //有异常时  异常步骤报异常 非异常代码段还是可以执行
//        CompletableFutureSimpleDemo.testSequence("-------------------");
        CompletableFutureSimpleDemo.testSequenceAndException("-------------------");

        System.out.println("=============");
        long end = System.currentTimeMillis();
        System.out.println(end - begin);
    }

}
